package cn.iocoder.yudao.module.erp.service.dp;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateTimeAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.dispatchvehicle.vo.DispatchVehicleSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpwsl.vo.DpWslPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpwsl.vo.DpWslSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dispatchvehicle.DispatchVehicleDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpSignDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpWslDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemWslDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.supplierfleet.SupplierFleetDO;
import cn.iocoder.yudao.module.erp.dal.mysql.dispatchvehicle.DispatchVehicleMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpSignMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpWslMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpitem.DpItemWslMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.supplierfleet.SupplierFleetMapper;
import cn.iocoder.yudao.module.erp.service.dispatchvehicle.DispatchVehicleServiceImpl;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.DP_WEIGHT_OUTOF_MAX;


/**
 * ERP乌苏里仓库 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class DpWslServiceImpl implements DpWslService {

    @Resource
    private DpWslMapper dpWslMapper;
    @Resource
    private DpItemWslMapper dpItemWslMapper;
    @Resource
    private DispatchVehicleMapper dispatchVehicleMapper;
    @Resource
    private DispatchVehicleServiceImpl dispatchVehicleServiceImpl;
    @Resource
    private DpServiceImpl dpServiceImpl;
    @Resource
    private SupplierFleetMapper supplierFleetMapper;
    @Resource
    private DpSignMapper dpSignMapper;
    @Resource
    private DpMapper dpMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createDpWsl(DpWslSaveReqVO createReqVO) {
        // 插入
        DpWslDO dpWsl = BeanUtils.toBean(createReqVO, DpWslDO.class);
        dpWslMapper.insert(dpWsl);

        // 插入子表
        createDpItemWslList(dpWsl.getId(), createReqVO.getDpItemWsls());
        // 返回
        return dpWsl.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDpWsl(DpWslSaveReqVO updateReqVO) {
        // 更新
        DpWslDO updateObj = BeanUtils.toBean(updateReqVO, DpWslDO.class);
        dpWslMapper.updateById(updateObj);

        // 更新子表
        updateDpItemWslList(updateReqVO.getId(), updateReqVO.getDpItemWsls());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDpWsl(String id) {
        // 删除
        dpWslMapper.deleteById(id);

        // 删除子表
        deleteDpItemWslByNo(id);
    }

    @Override
    public DpWslDO getDpWsl(String id) {
        return dpWslMapper.selectById(id);
    }

    @Override
    public PageResult<DpWslDO> getDpWslPage(DpWslPageReqVO pageReqVO) {
        Integer arrStatus = pageReqVO.getArrStatus();
        PageResult<DpWslDO> result;
        if (arrStatus != null && arrStatus == 1){
            result = dpWslMapper.selectPage(pageReqVO);
        } else {
            result = dpWslMapper.getDpWslPage(pageReqVO);
        }
        return result;
    }

    @Override
    public PageResult<DpWslDO> dpWslOuterList(DpWslPageReqVO pageReqVO) {
        return dpWslMapper.selectRemCountNoZeroPage(pageReqVO);
    }

    @Override
    public void dpWslOutStroe(DispatchVehicleSaveReqVO createReqVO) {
        //修改当前单的数据
        List<DpWslDO> dpWslDOList= createReqVO.getDpWslDOList();
        dpWslDOList.forEach(item -> item.setArrStatus(1));
        //修改运表单数据
        for (DpWslDO dpWslDO : dpWslDOList) {
            dpWslDO.setDispatchNumber(createReqVO.getDispatchNumber());
            //设置剩余件数 = 剩余总件数 - 出库件数
            Integer outCount = dpWslDO.getOutCount();
            int remCount = dpWslDO.getRemCount() - (outCount == null ? 0 : outCount);
            if (remCount < 0) {
                throw exception(DP_COUNT_OUTOF_MAX);
            }else {
                dpWslDO.setRemCount(remCount);
            }
            //设置剩余体积 = 剩余总体积 - 出库体积
            Double outVolume = dpWslDO.getOutVolume();
            double remVolume = dpWslDO.getRemVolume() - (outVolume == null ? 0 : outVolume);
            if (remVolume < 0) {
                throw exception(DP_VOLUME_OUTOF_MAX);
            }else {
                dpWslDO.setRemVolume(remVolume);
            }
            //设置剩余重量 = 剩余总重量 - 出库重量
            Double outWeight = dpWslDO.getOutWeight();
            double remWeight = dpWslDO.getRemWeight() - (outWeight == null ? 0 : outWeight);
            if (remWeight < 0) {
                throw exception(DP_WEIGHT_OUTOF_MAX);
            }else {
                dpWslDO.setRemWeight(remWeight);
            }
        }

        //批量修改制单数据
        dpWslMapper.updateById(dpWslDOList);

        //处理配车表数据
        List<DispatchVehicleDO> dispDOs = new ArrayList<DispatchVehicleDO>();
        for (DpWslDO dpWslDO : dpWslDOList) {
            DispatchVehicleDO vehicleDO = BeanUtils.toBean(createReqVO, DispatchVehicleDO.class);
            //处理车数据
            vehicleDO.setDpId(dpWslDO.getId());
            vehicleDO.setNo(dpWslDO.getNo());
            vehicleDO.setDispatchNumber(createReqVO.getDispatchNumber());
            vehicleDO.setInventoryStatus(1);
            // 使用 Gson 将 dpYwDO 转换为 JSON 字符串
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            String dpDataJson = gson.toJson(dpWslDO);  // LocalDateTime 字段会被跳过
            // 设置 JSON 字符串到 createReqVO 的 dpData 字段
            vehicleDO.setDpData(dpDataJson);
            dispDOs.add(vehicleDO);
        }
        // 批量插入配车数据
        dispatchVehicleMapper.insertBatch(dispDOs);

        //插入数据到供应商车队
        List<DispatchVehicleDO> supplierList = createReqVO.getSupplierInfo();
        String dispatchNumber = createReqVO.getDispatchNumber();
        String department = createReqVO.getDepartment();
        //处理时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(new Date());
        createReqVO.setDate(formattedDate);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        String recordDate = sdf2.format(new Date());
        createReqVO.setRecordDate(recordDate);
        createReqVO.setDpWslDOList(null);
        createReqVO.setSupplierInfo(null);
        List<SupplierFleetDO> fleetDOS = new ArrayList<>();
        for (DispatchVehicleDO supplierInfo : supplierList) {
            String fleet = supplierInfo.getFleet();
            if (fleet == null || fleet.trim().equals("")) {
                continue;
            }
            SupplierFleetDO supplierFleetDO = new SupplierFleetDO();
            supplierFleetDO.setType(1);
            supplierFleetDO.setCategory(supplierInfo.getCategory());
            supplierFleetDO.setName(supplierInfo.getSupplier());
            supplierFleetDO.setFleet(fleet);
            supplierFleetDO.setTotalAmount(supplierInfo.getExpense());
            //出库设置币种
            supplierFleetDO.setCurrencyType(supplierInfo.getCurrencyType());
            supplierFleetDO.setRemark(dispatchNumber);
            supplierFleetDO.setDepartment(department);

            // 处理info字段
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            createReqVO.setCategory(supplierInfo.getCategory());
            createReqVO.setSupplier(supplierInfo.getSupplier());
            createReqVO.setFleet(fleet);
            createReqVO.setFare(supplierInfo.getFare());
            createReqVO.setExpense(supplierInfo.getExpense());
            createReqVO.setCurrencyType(supplierInfo.getCurrencyType());
            createReqVO.setRemark(dispatchNumber);
            createReqVO.setDepartment(department);
            String info = gson.toJson(createReqVO);
            supplierFleetDO.setInfo(info);
            fleetDOS.add(supplierFleetDO);
        }
        supplierFleetMapper.insertBatch(fleetDOS);
    }


    // ==================== 子表（ERP乌苏里制单货号详情） ====================

    @Override
    public List<DpItemWslDO> getDpItemWslListByNo(String no) {
        return dpItemWslMapper.selectListByNo(no);
    }

    private void createDpItemWslList(String no, List<DpItemWslDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpItemWslMapper.insertBatch(list);
    }

    private void updateDpItemWslList(String no, List<DpItemWslDO> list) {
        deleteDpItemWslByNo(no);
        createDpItemWslList(no, list);
    }

    private void deleteDpItemWslByNo(String no) {
        dpItemWslMapper.deleteByNo(no);
    }

    @Override
    public List<DispatchVehicleDO> dpWslEnterList(String dispatchNumber, Integer line, Integer inventoryStatus, Integer dest,String dpId) {
        return dispatchVehicleMapper.selectByDispatch(dispatchNumber, line, inventoryStatus, dest,dpId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enterStroeDpWsl(List<DispatchVehicleSaveReqVO> pageReqVO) {
        List<DispatchVehicleDO> list = BeanUtils.toBean(pageReqVO, DispatchVehicleDO.class);
        for (DispatchVehicleDO dispatchVehicleDO : list) {
            String dpData= dispatchVehicleDO.getDpData();
            JSONObject jsonObject = JSONObject.parseObject(dpData);
            DpWslDO dpWslDO = JSONObject.toJavaObject(jsonObject, DpWslDO.class);

            dpWslDO.setRemCount((Integer) jsonObject.get("outCount"));
            BigDecimal outVolume = jsonObject.getBigDecimal("outVolume");
            dpWslDO.setRemVolume(outVolume.doubleValue());
            BigDecimal outWeight = jsonObject.getBigDecimal("outWeight");
            dpWslDO.setRemWeight(outWeight.doubleValue());
            DpWslDO dpWslDO1 = dpWslMapper.selectById(dpWslDO.getId());
            dpWslDO.setInventoryStatus(2);
            if (dpWslDO1 != null) {
                dpWslDO.setRemCount(dpWslDO.getRemCount() + dpWslDO1.getRemCount());
                dpWslDO.setRemVolume(dpWslDO.getRemVolume() + dpWslDO1.getRemVolume());
                dpWslDO.setRemWeight(dpWslDO.getRemWeight() + dpWslDO1.getRemWeight());
                dpWslMapper.updateById(dpWslDO);
            } else {
                dpWslMapper.insert(dpWslDO);
            }

            dpMapper.enterDpStart(dpWslDO.getId());

            dispatchVehicleMapper.updateById(dispatchVehicleDO.setInventoryStatus(2));

            dpServiceImpl.arrDataDpUpdata(dpWslDO.getId(),(Integer) jsonObject.get("outCount"),outVolume.doubleValue(),outWeight.doubleValue());
        }
    }

    @Override
    public void signDp(DpWslSaveReqVO updateReqVO) {
        Integer signStatus = updateReqVO.getSignStatus();
        Integer signNum = updateReqVO.getSignNum();
        Integer num = updateReqVO.getNum();
        Integer inCount = updateReqVO.getInCount();
        int signCount = signNum + num;
        int remCount = inCount - updateReqVO.getRemCount();
        if (signStatus == 2 && signCount > remCount) {
            throw exception(DP_SIGN_Count);
        }
        DpWslDO dpWslDO = BeanUtils.toBean(updateReqVO, DpWslDO.class);
        dpWslDO.setSignNum(signCount);
        if (signCount == remCount) {
            dpWslDO.setPickStatus(1);
        }
        if (updateReqVO.getSignStatus() == 2) {
            if (signCount == remCount) {
                dpWslDO.setArrStatus(2);
            }
            dispatchVehicleServiceImpl.updateDpData(updateReqVO.getId(), updateReqVO.getInCount(), updateReqVO.getSignNum(), updateReqVO.getNum());
        }
        dpWslMapper.updateById(dpWslDO);

        String id = updateReqVO.getId();
        updateReqVO.setId(null);
        DpSignDO dpSignDO = BeanUtils.toBean(updateReqVO, DpSignDO.class);
        dpSignDO.setDpId(id);
        dpSignDO.setSignNum(updateReqVO.getNum());
        dpSignDO.setStoreType(10);
        dpSignMapper.insert(dpSignDO);
    }

}